-- Base
-- Create by weism
-- 一些接口封装，不好归类仍这里了

sys_tonumber = sys_tonumber or tonumber;
sys_random = sys_random or math.random;

-- 三元运算符
function iif(condition, a, b)
    if condition then
        return a;
    else
        return b;
    end
end

-- 重载tonumber
function tonumber(num, idx)
    return sys_tonumber(num, idx) or 0;
end

-- 重载math.random
function math.random(a, b)
    if not b then
        return sys_random(a);
    end

    if a <= b then
        return sys_random(a, b);
    else
        return sys_random(b, a);
    end
end

-- 调用Java接口
function callJavaFunc(func, args, sigs)
    if RELEASE_LOG_ENABLED ~= 1 then
        print("call java method:"..func);
    end
    local count = #args;
    local n = 0;
    for k, v in pairs(args) do
        n = n + 1;
    end

    if count ~= n then
        error("nil arguments when calling func:"..func);
    end

    local luaj = require "cocos.cocos2d.luaj";
    local className = "org/cocos2dx/lib/Cocos2dxLuaJavaBridge";
    local ok, ret = luaj.callStaticMethod(className, func, args, sigs);
    if not ok then
        if RELEASE_LOG_ENABLED ~= 1 then
            print("luaj error");
        end
    end

    return ret;
end

-- 调用Java接口
function callJavaFuncWithClass(className, func, args, sigs)
    if RELEASE_LOG_ENABLED ~= 1 then
        print("call java method:"..className.."::"..func);
    end

    local luaj = require "cocos.cocos2d.luaj";
    local ok, ret = luaj.callStaticMethod(className, func, args, sigs);
    if not ok then
        if RELEASE_LOG_ENABLED ~= 1 then
            print("luaj error");
        end
    end

    return ret;
end

-- 调用Object-C接口
function callOCFunc(func, args)
    local luaoc = require "cocos.cocos2d.luaoc";
    local className = "LuaObjectCBridge";
    local ok,ret  = luaoc.callStaticMethod(className, func, args);
    if not ok then
        print("luaoc error");
    end

    return ret;
end

function callOCFuncWithClass(className, func, args)
    local luaoc = require "cocos.cocos2d.luaoc";
    local ok,ret  = luaoc.callStaticMethod(className, func, args);
    if not ok then
        print("luaoc error");
    end

    return ret;
end

local verifyClient = false;
-- 是否验证客户端，暂时放这里
function isVerifyClient()
    if IS_VERIFY_CLIENT == 1 then
        return true;
    end

    -- 播放录像也算
    if isReplayingRecord() then
        return true;
    end

    return verifyClient == true;
end

-- 标记为验证客户端
function defineVerifyClient(flag)
    verifyClient = flag or false;
end

-- 播放录像状态
local replayingRecord = false;
function isReplayingRecord()
    return replayingRecord;
end

function switchReplaying(state)
    replayingRecord = state;
end

function sizeof(t)
    local n = 0;
    if type(t) == "table" then
        -- 遍历 table，累加元素个数
        for __, __ in pairs(t) do
            n = n + 1;
        end
    elseif type(t) == "string" then
        n = string.len(t);
    end

    return n;
end

function is_array(t)
    if type(t) ~= "table" then
        return false;
    end

    if t["__mapping"] then
        return false;
    end

    local size = sizeof(t);
    if size == 0 then
        return true;
    end

    if size == table.getn(t) and t[1] then
        return true;
    end

    return false;
end

function is_mapping(t)
    if type(t) ~= "table" then
        return false;
    end

    if t["__mapping"] then
        return true;
    end

    if table.getn(t) == sizeof(t) then
        return false;
    end

    return true;
end

function to_mapping(t)
    if type(t) ~= "table" then
        return t;
    end

    local ret = table.copy(t);

    ret.__mapping = 1;

    return ret;
end

-- 整理数组
function clean_array(t)
    if not t then
        return
    end

    local n = 1;
    local v, p, max;
    local type = type;

    max = table.maxn(t);
    for i = 1, max do
        v = t[i];
        p = type(v);
        if p ~= "nil" then
            -- 需要重新整理数组
            t[n] = v;
            n = n + 1;
        end
    end

    -- 清除剩余的记录
    for i = n, max do
        t[i] = nil;
    end

    return t, n - 1;
end

-- 函数调用保护catch
function catch(func, ...)
    local args = { ... };
    local status, ret1, ret2, ret3 = xpcall(
            function()
                return func(unpack(args));
            end,
            function(msg)
                return msg.."\n"..debug.traceback();
            end);
    if not status then
        recordTraceback(ret1);
    else
        return ret1, ret2, ret3;
    end
end
